#pragma once

#include <struct/query_context.hpp>
#include "struct/context_operations.hpp"
#include <serialization/writer_options.hpp>
#include <data/db_connection_options.hpp>

namespace blitz_query_cpp
{
    template <class ReaderT>
    class execute_sql
    {
        ReaderT reader;

    public:
        bool process(query_context &context)
        {
            bool have_sql = context.data.contains("sql");
            if (!have_sql)
            {
                return true;
            }

            if (!context.document.operation)
                context.report_error("Operation definition is missing");
            else if (!context.document.operation->selection_set)
                context.report_error("Root selection set is missing");
            else if (context.document.operation->selection_set->children.size() != 1)
                context.report_error("Query should have only one selection set");

            db_connection_options connection_options;
            connection_options.connection_string = context.data["connection_string"];

            bool connected = reader.connect(connection_options);
            if (!connected)
            {
                return context.report_error("Error connecting data reader: {}", reader.get_error_msg());
            }

            std::string_view sql = context.data["sql"];
            std::vector<const char *> params;
            if (!reader.execute_sql(sql, params))
            {
                return context.report_error("Error executing data reader: {}", reader.get_error_msg());
            }

            return true;
        }
    };
}
